home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / mesademos / GEARS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  7.7 KB  |  331 lines

  1. /* gears.c */
  2.  
  3. /*
  4.  * 3-D gear wheels.  This program is in the public domain.
  5.  *
  6.  * Brian Paul
  7.  */
  8.  
  9. /* Conversion to GLUT by Mark J. Kilgard */
  10.  
  11. #include <math.h>
  12. #include <stdlib.h>
  13. #include <GL/glut.h>
  14.  
  15. #ifndef M_PI
  16. #define M_PI 3.14159265
  17. #endif
  18.  
  19. /**
  20.  
  21.   Draw a gear wheel.  You'll probably want to call this function when
  22.   building a display list since we do a lot of trig here.
  23.  
  24.   Input:  inner_radius - radius of hole at center
  25.           outer_radius - radius at center of teeth
  26.           width - width of gear
  27.           teeth - number of teeth
  28.           tooth_depth - depth of tooth
  29.  
  30.  **/
  31.  
  32. static void
  33. gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
  34.   GLint teeth, GLfloat tooth_depth)
  35. {
  36.   GLint i;
  37.   GLfloat r0, r1, r2;
  38.   GLfloat angle, da;
  39.   GLfloat u, v, len;
  40.  
  41.   r0 = inner_radius;
  42.   r1 = outer_radius - tooth_depth / 2.0;
  43.   r2 = outer_radius + tooth_depth / 2.0;
  44.  
  45.   da = 2.0 * M_PI / teeth / 4.0;
  46.  
  47.   glShadeModel(GL_FLAT);
  48.  
  49.   glNormal3f(0.0, 0.0, 1.0);
  50.  
  51.   /* draw front face */
  52.   glBegin(GL_QUAD_STRIP);
  53.   for (i = 0; i <= teeth; i++) {
  54.     angle = i * 2.0 * M_PI / teeth;
  55.     glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  56.     glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  57.     glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  58.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
  59.   }
  60.   glEnd();
  61.  
  62.   /* draw front sides of teeth */
  63.   glBegin(GL_QUADS);
  64.   da = 2.0 * M_PI / teeth / 4.0;
  65.   for (i = 0; i < teeth; i++) {
  66.     angle = i * 2.0 * M_PI / teeth;
  67.  
  68.     glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  69.     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
  70.     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
  71.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
  72.   }
  73.   glEnd();
  74.  
  75.   glNormal3f(0.0, 0.0, -1.0);
  76.  
  77.   /* draw back face */
  78.   glBegin(GL_QUAD_STRIP);
  79.   for (i = 0; i <= teeth; i++) {
  80.     angle = i * 2.0 * M_PI / teeth;
  81.     glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  82.     glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  83.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
  84.     glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  85.   }
  86.   glEnd();
  87.  
  88.   /* draw back sides of teeth */
  89.   glBegin(GL_QUADS);
  90.   da = 2.0 * M_PI / teeth / 4.0;
  91.   for (i = 0; i < teeth; i++) {
  92.     angle = i * 2.0 * M_PI / teeth;
  93.  
  94.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
  95.     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
  96.     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
  97.     glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  98.   }
  99.   glEnd();
  100.  
  101.   /* draw outward faces of teeth */
  102.   glBegin(GL_QUAD_STRIP);
  103.   for (i = 0; i < teeth; i++) {
  104.     angle = i * 2.0 * M_PI / teeth;
  105.  
  106.     glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
  107.     glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
  108.     u = r2 * cos(angle + da) - r1 * cos(angle);
  109.     v = r2 * sin(angle + da) - r1 * sin(angle);
  110.     len = sqrt(u * u + v * v);
  111.     u /= len;
  112.     v /= len;
  113.     glNormal3f(v, -u, 0.0);
  114.     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
  115.     glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
  116.     glNormal3f(cos(angle), sin(angle), 0.0);
  117.     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
  118.     glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
  119.     u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
  120.     v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
  121.     glNormal3f(v, -u, 0.0);
  122.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
  123.     glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
  124.     glNormal3f(cos(angle), sin(angle), 0.0);
  125.   }
  126.  
  127.   glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
  128.   glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
  129.  
  130.   glEnd();
  131.  
  132.   glShadeModel(GL_SMOOTH);
  133.  
  134.   /* draw inside radius cylinder */
  135.   glBegin(GL_QUAD_STRIP);
  136.   for (i = 0; i <= teeth; i++) {
  137.     angle = i * 2.0 * M_PI / teeth;
  138.     glNormal3f(-cos(angle), -sin(angle), 0.0);
  139.     glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
  140.     glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
  141.   }
  142.   glEnd();
  143.  
  144. }
  145.  
  146. static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
  147. static GLint gear1, gear2, gear3;
  148. static GLfloat angle = 0.0;
  149.  
  150. static GLuint limit;
  151. static GLuint count = 1;
  152.  
  153. static void
  154. draw(void)
  155. {
  156.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  157.  
  158.   glPushMatrix();
  159.   glRotatef(view_rotx, 1.0, 0.0, 0.0);
  160.   glRotatef(view_roty, 0.0, 1.0, 0.0);
  161.   glRotatef(view_rotz, 0.0, 0.0, 1.0);
  162.  
  163.   glPushMatrix();
  164.   glTranslatef(-3.0, -2.0, 0.0);
  165.   glRotatef(angle, 0.0, 0.0, 1.0);
  166.   glCallList(gear1);
  167.   glPopMatrix();
  168.  
  169.   glPushMatrix();
  170.   glTranslatef(3.1, -2.0, 0.0);
  171.   glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
  172.   glCallList(gear2);
  173.   glPopMatrix();
  174.  
  175.   glPushMatrix();
  176.   glTranslatef(-3.1, 4.2, 0.0);
  177.   glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
  178.   glCallList(gear3);
  179.   glPopMatrix();
  180.  
  181.   glPopMatrix();
  182.  
  183.   glutSwapBuffers();
  184.  
  185.   count++;
  186.   if (count == limit) {
  187.     exit(0);
  188.   }
  189. }
  190.  
  191. static void
  192. idle(void)
  193. {
  194.   angle += 2.0;
  195.   glutPostRedisplay();
  196. }
  197.  
  198. /* change view angle, exit upon ESC */
  199. /* ARGSUSED1 */
  200. static void
  201. key(unsigned char k, int x, int y)
  202. {
  203.   switch (k) {
  204.   case 'z':
  205.     view_rotz += 5.0;
  206.     break;
  207.   case 'Z':
  208.     view_rotz -= 5.0;
  209.     break;
  210.   case 27:  /* Escape */
  211.     exit(0);
  212.     break;
  213.   default:
  214.     return;
  215.   }
  216.   glutPostRedisplay();
  217. }
  218.  
  219. /* change view angle */
  220. /* ARGSUSED1 */
  221. static void
  222. special(int k, int x, int y)
  223. {
  224.   switch (k) {
  225.   case GLUT_KEY_UP:
  226.     view_rotx += 5.0;
  227.     break;
  228.   case GLUT_KEY_DOWN:
  229.     view_rotx -= 5.0;
  230.     break;
  231.   case GLUT_KEY_LEFT:
  232.     view_roty += 5.0;
  233.     break;
  234.   case GLUT_KEY_RIGHT:
  235.     view_roty -= 5.0;
  236.     break;
  237.   default:
  238.     return;
  239.   }
  240.   glutPostRedisplay();
  241. }
  242.  
  243. /* new window size or exposure */
  244. static void
  245. reshape(int width, int height)
  246. {
  247.   GLfloat h = (GLfloat) height / (GLfloat) width;
  248.  
  249.   glViewport(0, 0, (GLint) width, (GLint) height);
  250.   glMatrixMode(GL_PROJECTION);
  251.   glLoadIdentity();
  252.   glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
  253.   glMatrixMode(GL_MODELVIEW);
  254.   glLoadIdentity();
  255.   glTranslatef(0.0, 0.0, -40.0);
  256. }
  257.  
  258. static void
  259. init(void)
  260. {
  261.   static GLfloat pos[4] =
  262.   {5.0, 5.0, 10.0, 0.0};
  263.   static GLfloat red[4] =
  264.   {0.8, 0.1, 0.0, 1.0};
  265.   static GLfloat green[4] =
  266.   {0.0, 0.8, 0.2, 1.0};
  267.   static GLfloat blue[4] =
  268.   {0.2, 0.2, 1.0, 1.0};
  269.  
  270.   glLightfv(GL_LIGHT0, GL_POSITION, pos);
  271.   glEnable(GL_CULL_FACE);
  272.   glEnable(GL_LIGHTING);
  273.   glEnable(GL_LIGHT0);
  274.   glEnable(GL_DEPTH_TEST);
  275.  
  276.   /* make the gears */
  277.   gear1 = glGenLists(1);
  278.   glNewList(gear1, GL_COMPILE);
  279.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
  280.   gear(1.0, 4.0, 1.0, 20, 0.7);
  281.   glEndList();
  282.  
  283.   gear2 = glGenLists(1);
  284.   glNewList(gear2, GL_COMPILE);
  285.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
  286.   gear(0.5, 2.0, 2.0, 10, 0.7);
  287.   glEndList();
  288.  
  289.   gear3 = glGenLists(1);
  290.   glNewList(gear3, GL_COMPILE);
  291.   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
  292.   gear(1.3, 2.0, 0.5, 10, 0.7);
  293.   glEndList();
  294.  
  295.   glEnable(GL_NORMALIZE);
  296. }
  297.  
  298. void 
  299. visible(int vis)
  300. {
  301.   if (vis == GLUT_VISIBLE)
  302.     glutIdleFunc(idle);
  303.   else
  304.     glutIdleFunc(NULL);
  305. }
  306.  
  307. int
  308. main(int argc, char *argv[])
  309. {
  310.   glutInit(&argc, argv);
  311.   if (argc > 1) {
  312.     /* do 'n' frames then exit */
  313.     limit = atoi(argv[1]) + 1;
  314.   } else {
  315.     limit = 0;
  316.   }
  317.   glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
  318.  
  319.   glutCreateWindow("Gears");
  320.   init();
  321.  
  322.   glutDisplayFunc(draw);
  323.   glutReshapeFunc(reshape);
  324.   glutKeyboardFunc(key);
  325.   glutSpecialFunc(special);
  326.   glutVisibilityFunc(visible);
  327.  
  328.   glutMainLoop();
  329.   return 0;             /* ANSI C requires main to return int. */
  330. }
  331.